/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Negocio;

import MapeamentoPersistencia.AdaptadorPersistencia;
import Persistencia.InterfaceCadastroDTO;
import Persistencia.DAOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 *
 * @author v3550
 */


public class CadastroFachada<T> {

    private InterfaceCadastro dao = null;
    private List<CadastroListener> listeners;
    //strategy
    protected LanceVencedor vencedor;

    public CadastroFachada() throws CadastroException, DAOException, Exception {
        dao = AdaptadorPersistencia.getInstance();
        // dao = new AdaptadorPersistencia();
        listeners = new ArrayList<CadastroListener>();

    }

    public void addCadastroListener(CadastroListener l) {
        if (!listeners.contains(l)) {
            listeners.add(l);
        }
    }

    public void removeCadastroListener(CadastroListener l) {
        listeners.remove(l);
    }

    protected <T> void fireElementoAdicionado(T p) {
        CadastroEvent evt = new CadastroEvent(this, p);
        for (CadastroListener l : listeners) {
            l.elementoAdicionado(evt);
        }
    }

    public Categoria adicionarCategoria(String categoria) throws CadastroException {
        if (!Validar.getInstace().validaString(categoria)) {
            throw new CadastroException("Nome da categoria inválida!");
        }

        Categoria c = new Categoria();
        c.setNome(categoria);

        try {
            boolean ok = dao.adicionarCategoria(c);
            if (ok) {
                fireElementoAdicionado(c);
                return c;
            }
            return null;
        } catch (DAOException e) {
            throw new CadastroException("Falha ao adicionar categoria!", e);
        }
    }

    public Usuario adicionarUsuario(String nome, String email) throws CadastroException {
        if (!Validar.getInstace().validaString(nome)) {
            throw new CadastroException("Nome do usuário inválido!");
        }

        if (!Validar.getInstace().validaEmail(email)) {
            throw new CadastroException("email inválido!");
        }

        Usuario c = new Usuario();
        c.setNome(nome);
        c.setEmail(email);

        try {
            boolean ok = dao.adicionarUsuario(c);
            if (ok) {
                fireElementoAdicionado(c);
                return c;
            }
            return null;
        } catch (DAOException e) {
            throw new CadastroException("Falha ao adicionar Usuario!", e);
        }
    }

    public Artigo adicionarArtigo(String nome, String user, String categ, String qtd, String dtIni, String dtFim, String hrIni, String hrFim, String vlr, String politicaVencedor) throws CadastroException, DAOException {
        if (politicaVencedor.equals(" ")) {
            throw new CadastroException("Favor informar o critério para definir o vencedor");
        }

        if (!Validar.getInstace().validaInteger(user)) {
            throw new CadastroException("Usuário inválido!");
        }

        if (!Validar.getInstace().validaInteger(categ)) {
            throw new CadastroException("Categoria Inválida");
        }


        if (!Validar.getInstace().validaString(nome)) {
            throw new CadastroException("Nome do artigo inválido!");
        }


        java.sql.Date DtIni = Validar.getInstace().validaData(dtIni);
        if (DtIni == null) {
            throw new CadastroException("Data inicial Inválida");
        }
        java.sql.Time HrIni = Validar.getInstace().validaHora(hrIni);

        if (HrIni == null) {
            throw new CadastroException("Hora inicial Inválida");
        }

        java.sql.Date DtFim = Validar.getInstace().validaData(dtFim);

        if (DtFim == null) {
            throw new CadastroException("Data final Inválida");
        }

        java.sql.Time HrFim = Validar.getInstace().validaHora(hrFim);
        if (HrFim == null) {
            throw new CadastroException("Hora final Inválida");
        }

        if (!Validar.getInstace().validaInteger(qtd)) {
            throw new CadastroException("Quantidade Inválida");
        }


        if (!Validar.getInstace().validaDouble(vlr)) {
            throw new CadastroException("Valor do artigo Inválido");
        }

        Artigo a = new Artigo();

        a.setUsuario(Integer.parseInt(user));
        a.setCategoria(Integer.parseInt(categ));

        a.setPoliticaVencedor(politicaVencedor);
        a.setNome(nome);

        a.setQtdItensVenda(Integer.parseInt(qtd));
        a.setValorInicial(Double.parseDouble(vlr));

        a.setDataInicial(DtIni);
        a.setDataFinal(DtFim);

        a.setHoraInicial(HrIni);
        a.setHorafinal(HrFim);

        try {
            boolean ok = dao.adicionarArtigo(a);
            if (ok) {
                fireElementoAdicionado(a);
                return a;
            }
            return null;
        } catch (DAOException e) {
            throw new CadastroException("Falha ao adicionar Usuario!", e);
        }

    }

    public List<Usuario> BuscarUsuarios() throws CadastroException {
        try {
            return dao.getUsuarios();
        } catch (DAOException e) {
            throw new CadastroException("Falha ao buscar os usuários!", e);
        }
    }

    public List<Usuario> BuscarUsuariosParaLance(Artigo a) throws CadastroException {
        try {
            return dao.getUsuariosParaLance(a);
        } catch (DAOException e) {
            throw new CadastroException("Falha ao buscar os usuários!", e);
        }
    }

    public List<Categoria> BuscarCategorias() throws CadastroException {
        try {
            return dao.getCategorias();
        } catch (DAOException e) {
            throw new CadastroException("Falha em buscar as categorias!", e);
        }
    }

    public List<Artigo> BuscarArtigos() throws CadastroException {
        try {
            return dao.getArtigos();
        } catch (DAOException e) {
            throw new CadastroException("Falha ao buscar os artigos!", e);
        }
    }

    public List<Artigo> BuscarArtigosFechado() throws CadastroException {
        try {
            return dao.getArtigoFechado();
        } catch (DAOException e) {
            throw new CadastroException("Falha ao buscar os leilões fechados!", e);
        }
    }

    public List<Artigo> BuscarArtigosAberto() throws CadastroException {
        try {
            return dao.getArtigoAberto();
        } catch (DAOException e) {
            throw new CadastroException("Falha ao buscar os leilões abertos!", e);
        }
    }

    public List<Lance> BuscarLance(Artigo a) throws CadastroException {
        try {
            return dao.getLance(a);
        } catch (DAOException e) {
            throw new CadastroException("Falha ao buscar os lances!", e);
        }
    }

    public Lance adicionarLance(String usuario, String valor, int artigo, double lastLance) throws CadastroException, DAOException {

        if (!Validar.getInstace().validaInteger(usuario)) {
            throw new CadastroException("Usuário Inválida");
        }

        if (!Validar.getInstace().validaDouble(valor)) {
            throw new CadastroException("Valor do lance Inválido");
        }
        if(Double.parseDouble(valor) < lastLance)
        {
            throw new CadastroException("Seu lance tem que ser maior que " + lastLance);
        }
        
        if(!validaDataHoraLance(artigo))
        {
            throw new CadastroException("Desculpe, encerrou o leilão ! ");
        }

        Lance l = new Lance();
        l.setId_usuario(Integer.parseInt(usuario));
        l.setLance(Double.parseDouble(valor));
        l.setId_artigo(artigo);

        try {
            boolean ok = dao.adicionarLance(l);
            if (ok) {
                fireElementoAdicionado(l);
                return l;
            }
            return null;

        } catch (DAOException e) {
            throw new CadastroException("Falha ao buscar os lances!", e);
        }
    }
    
    public double getValorMinimoLance(Artigo a) throws DAOException
    {
        return dao.getValorMínimoLance(a);
    }
    
    public void setVencedor(LanceVencedor lvenc)
    {
        this.vencedor = lvenc;
    }

    public Lance getLanceVencedor(Artigo a) throws DAOException
     {
        Lance lance = new Lance();  
        switch (a.getPoliticaVencedor()) {
            case "S":
                lance.setVencedor(new LanceMaximo());
                break;
            case "N":
                lance.setVencedor(new LanceMinimo());
                break;
        }
       
        return lance.getVencedor(a);
     }
    
     public boolean validaDataHoraLance(int a) throws DAOException
     {
          return dao.validaDataHoraLeilao(a);
     }
     
     public boolean encerrarLeilao(int a) throws DAOException
     {
        return dao.fecharLeilao(a);
     }
}
